﻿function ECommerceProductReviewDetailsViewModel(context) {

    var self = this;

    var spinner = new SpinnerModel();

    var dispatcher = $({});

    var productsByTag = context.spaRuntime.findRouteByName('productsByTag');

    var product = ko.observable(new FullProductModel());
    var productId = null;
    var review = ko.observable(null);

    var isNew = ko.observable(false);

    function getTimestamp() {
        var date = new Date();
        var res = '';
        res += date.getFullYear();
        res += '-';

        var month = date.getMonth() + 1;
        if (month < 10) res += '0' + month;
        else res += month;

        res += '-';

        var day = date.getDate();
        if (day < 10) res += '0' + day;
        else res += day;

        res += ' ';

        var hours = date.getHours();
        if (hours < 10) res += '0' + hours;
        else res += hours;

        res += '-';

        var minutes = date.getMinutes();
        if (minutes < 10) res += '0' + minutes;
        else res += minutes;

        res += '-';

        var seconds = date.getSeconds();
        if (seconds < 10) res += '0' + seconds;
        else res += seconds;

        return res;
    }
    
    function generateId() {
        var id = getTimestamp();
        id = getHash(id);
        id = Math.abs(id);
        return id;
    }
    
    function getHash(str) {
        var hash = 5381;
        for (var i = 0; i < str.length; i++) {
            var ch = str.charCodeAt(i);
            hash = ((hash << 5) + hash) + ch; /* hash * 33 + c */
        }
        return hash % 2000000000;
    }
    
    var viewUrl = ko.computed(function () {
        var pr = product();
        if (!pr) return null;
        return context.spaRuntime.findRouteByName('product').formatHash({
            id: pr.id()
        });
    });

    function submit() {
        var pr = review();
        if (utils.isNullOrWhiteSpace(pr.comments())) return;

        var info = pr.getInfo();
        var api = context.api();
        if (!isNew()) {
            spinner.enter();
            api.reviews.updateReview(productId, pr.id(), info, function () {
                spinner.leave();
                goToProduct();
                dispatcher.trigger('success');
            }, function () {
                spinner.leave();
            });
        } else {
            spinner.enter();
            api.reviews.submit(productId, info, function () {
                spinner.leave();
                window.location.hash = viewUrl();
                dispatcher.trigger('success');
            }, function () {
                spinner.leave();
            });
        }
    }

    function removeReview() {
        if (!isNew()) {
            var api = context.api();
            spinner.enter();
            api.reviews.removeReview(productId, review().id(), function () {
                spinner.leave();
                goToProduct();
                dispatcher.trigger('success');
            }, function () {
                spinner.leave();
            });
        }
    }

    function goToProduct() {
        context.spaRuntime.findRouteByName('product').navigateHash({
            id: productId
        });
    }
    
    function reloadProduct(prodId) {
        productId = prodId;
        var api = context.api();
        spinner.enter();
        api.products.getById(prodId, function (response) {
            spinner.leave();
            var pr = new FullProductModel(response);
            product(pr);
        }, function () {
            var pr = new FullProductModel();
            product(pr);
            spinner.leave();
        });
    }

    function showFor(prodId, reviewId) {
        reloadProduct(prodId);
        isNew(false);
        var api = context.api();
        spinner.enter();
        api.reviews.getById(prodId, reviewId, function (response) {
            spinner.leave();

            var pr = new ProductReviewModel(response);
            review(pr);
            isNew(false);
        }, function () {
            spinner.leave();
            isNew(true);
        });
    }

    function showForNew(prodId) {
        isNew(true);
        reloadProduct(prodId);
        var pr = new ProductReviewModel();
        pr.id(generateId());
        pr.userId(context.userEmail());
        pr.reviewDate(getTimestamp());
        pr.productId(prodId);
        review(pr);
    }

    function getByTagUrl(tag) {
        return productsByTag.formatHash({
            tag: tag
        });
    }

    function addOnSuccess(handler) {
        dispatcher.bind('success', handler);
    }

    self.product = product;
    self.submit = submit;
    self.removeReview = removeReview;
    self.showFor = showFor;
    self.showForNew = showForNew;
    self.getByTagUrl = getByTagUrl;
    self.viewUrl = viewUrl;
    self.review = review;
    self.isNew = isNew;
    self.addOnSuccess = addOnSuccess;
}

